﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SIMCRepositorio;
using SIMCObjetoNegocio;
using SIMCReglasNegocio;

namespace SIMCFachadaNegocio
{
    public class FachadaSeguridad : FachadaBase
    {
        protected string TodosLosPermisos = "*******";
        protected string PermisosPropios = "USUARIO";

        IRepositorioConfiguracion m_ConfiguracionRepositorio = DatabaseAccess.ConfiguracionRepositorio;
        IRepositorioSeguridad m_SeguridadRepositorio = DatabaseAccess.SeguridadRepositorio;
        IRepositorioAtributoPersona m_AtributoPersonaRepositorio = DatabaseAccess.AtributoPersonaRepositorio;
        IRepositorioUsuario m_UsuarioRepositorio = DatabaseAccess.UsuarioRepositorio;

        #region FuncionConSeguridad y Permisos
        /// <summary>
        /// Crea una funcion con el Objeto, Evento y Descipcion indicada en el Atributo=SYS.  Valor=Acceso se almacena en cav_scal1=TipoRestriccionFuncion,  
        /// Cav_scal2=TipoPermiso, (G/U)  o Password si cav_sCal1='2' cav_scal3=Usuario o Perfil
        /// </summary>
        private FuncionConSeguridad CreaFuncion(string p_Objeto, string p_Evento, string p_Descripcion)
        {

            FuncionConSeguridad MiF = null;

            try
            {
                MiF = new FuncionConSeguridad();
                MiF.Descripcion = p_Descripcion;
                MiF.Evento = p_Evento;
                MiF.Objeto = p_Objeto;

                ConfiguracionSistema config = m_ConfiguracionRepositorio.BuscarConfiguracion("Acceso");
                MiF.TipoRestriccion = config.Configuracion1;

                MiF.ID = m_SeguridadRepositorio.CrearFuncionSeguridad(MiF);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            // Buscar en SYS.ACCESO. Inicializas 
            return MiF;
        }

        /// <summary>
        /// Devuelve la funcion con un objeto y evento en particular y si no existe lo crea.
        /// </summary>
        /// <param name="p_Objeto">Nombre de el objeto que tiene o tendrá seguridad</param>
        /// <param name="p_Evento">Nombre del evento (consultar,modificar,eliminar)</param>
        /// <param name="p_Descripcion">Descripcion del evento</param>
        /// <returns></returns>
        private FuncionConSeguridad BuscarFuncion(string p_Objeto, string p_Evento, string p_Descripcion)
        {
            // Busca en el repositorio la funcion
            // Si no la consigue la crea, llamando a CreaFuncion
            FuncionConSeguridad MiF = m_SeguridadRepositorio.BuscarFuncionConSeguridad(p_Objeto, p_Evento);
            if (MiF != null)
            {
                return MiF;
            }
            else
            {
                return CreaFuncion(p_Objeto, p_Evento, p_Descripcion);
            }
        }

        /// <summary>
        // Si la Funcion tiene seguridad=0 devuelve true
        // Si la funcion tiene seguridad=2 pide PWD y si coincide con la almacenada devuelve TRUE
        // Si la funcion tiene seguridad=1 busca el ID en la lista de Permisos de la sesión, devolviendo true si el usuario
        /// </summary>
        public bool BuscarPermiso(Usuario p_Usuario, FuncionConSeguridad p_funcion)
        {
            try
            {
                FuncionConSeguridad funcion = BuscarFuncion(p_funcion.Objeto, p_funcion.Evento, p_funcion.Descripcion);

                TipoRestriccionSeguridad validacion = new TipoRestriccionSeguridad(m_SeguridadRepositorio, p_Usuario,
                    funcion, p_funcion);

                return validacion.Validar();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<FuncionConSeguridad> BuscarListaFuncionConSeguridad(string p_Objeto, string p_Evento)
        {
            try
            {
                return m_SeguridadRepositorio.BuscarListaFuncionConSeguridad(p_Objeto, p_Evento);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<FuncionConSeguridad> BuscarListaPermiso(string p_Objeto, string p_Evento, int p_IdUsuario, string p_Perfil)
        {
            try
            {
                return m_SeguridadRepositorio.BuscarListaFuncionConSeguridad(p_Objeto, p_Evento, p_IdUsuario, p_Perfil);
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        #endregion

        public IList<Rol> BuscarListaRol(int p_IdUsuario)
        {
            try
            {
                return m_UsuarioRepositorio.BuscarRolesUsuario(p_IdUsuario);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        [Obsolete("Revisar la última version de SIMCNET antes de la migracion")]
        public int CambiaPasswordUsuario(string p_Login, string p_PassViejo, string p_PassNuevo, string p_PassNuevo2)
        {
            throw new NotImplementedException();
        }

        public int ValidarAcceso(string login, string pwd)
        {
            // devuelve >0 IDUsurio acceso permitido
            // devuelve -1 login no existe
            // devuelve -2 pwd no corresponde a login
            // devuelve -3 usuario inactivo
            // devuelve -4 usuario conectado ya en otra instancia
            // devuelve -5 hay mas de un usuario definido con ese login
            try
            {
                Usuario objeto = m_UsuarioRepositorio.BuscarUsuario(login);

                if (objeto != null)
                {
                    AgregarRegla(new UsuarioInactivo(m_SeguridadRepositorio, m_AtributoPersonaRepositorio,
                            m_UsuarioRepositorio, objeto));

                    if (!EsValido)
                        throw new ArgumentException(MostrarReglasRotas());

                    return objeto.Id;
                }
                else
                {
                    throw new Excepciones.FallaLoginException(string.Format("No se encontro el usuario {0}", login));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Usuario BuscarUsuario(int p_IDUser)
        {
            try
            {
                Usuario user = m_UsuarioRepositorio.BuscarUsuario(p_IDUser);
                user.Rol = m_UsuarioRepositorio.BuscarRolUsuarioPorDefecto(p_IDUser);
                return user;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IList<Usuario> BuscarUsuariosConRolExterno(string p_Login, string p_Nombre, string p_Email)
        {
            try
            {
                return m_UsuarioRepositorio.BuscarListaUsuarioExterno(p_Login, p_Nombre, p_Email);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Rol BuscarRolPorDefecto(int p_IdUsuario)
        {
            try
            {
                return m_UsuarioRepositorio.BuscarRolUsuarioPorDefecto(p_IdUsuario);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void ActualizarRolPorDefecto(int p_IdUsuario, string p_IdNuevoRol)
        {
            try
            {
                m_UsuarioRepositorio.ActualizarRolPorDefecto(p_IdUsuario, p_IdNuevoRol);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<string> BuscarPreguntasDeSeguridad()
        {
            try
            {
                return m_SeguridadRepositorio.BuscarPreguntasDeSeguridad();
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public List<Rol> BuscarRoles()
        {
            try
            {
                return m_UsuarioRepositorio.BuscarRoles();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
